home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
t3_1
/
nexttsrc.lha
/
nexttsources
/
sources
/
sys
/
ae_vmport.t
next >
Wrap
Text File
|
1988-02-05
|
14KB
|
437 lines
(herald aegis_vmport
(env tsys
(osys aegis_fault)
(osys buffer)))
;;; The Aegis interface to I/O routines.
;;; This file contains the virtual machine I/O interface to the
;;; aegis operating system. Where possible we use IOS calls rather
;;; than say NAME calls, so that T takes advantage of Extensible
;;; ports.
;;; Used on startup.
(define (%VM-BOOT-WRITE-TTY sym)
(vfmt "%A%." sym (symbol-length sym)))
(define-foreign vfmt ("VFMT_$WRITE2" (in rep/string)
(in rep/extend)
(in rep/integer))
ignore)
;;; Z system i/o
(define-set-of ios_$put_get_opts_t
ios_$cond_opt
ios_$preview_opt
ios_$partial_record_opt
ios_$no_rec_bndry_opt)
(define-constant %%standard-input 0)
(define-constant %%standard-output 1)
(define-constant %%error-input 2)
(define-constant %%error-output 3)
;;; Input
(define-constant aegis-eof #x01270009) ; ios_$end_of_file
(define-constant aegis-no-data #x0127003E) ; ios_$get_conditional_failed
(define (%VM-READ-BUFFER IOB BLOCK?)
(let ((get_opts (fx-ior (if block? ios_$cond_opt 0)
(if (iob-interactive? iob)
0
ios_$no_rec_bndry_opt))))
(receive (length status) (ios_$get (iob-channel iob)
get_opts
(iob-buffer iob)
(max-buffer-length iob)
nil)
;++ (format t "~&sts= ~x len= ~d~%" status length)
(cond ((fx= 0 status)
(set (iob-offset iob) 0)
(set (iob-limit iob) length)
(set (iob-eof-flag? iob) nil)
length)
((fx= aegis-no-data status)
nil)
((fx= aegis-eof status)
(set (iob-eof-flag? iob) t)
eof)
(else
(local-os-error status))))))
(define-foreign ios_$get
("IOS_$GET" (in rep/integer-16-u port-id)
(in rep/integer-16-u put-get-options)
(ignore rep/extend buffer)
(in rep/integer bufmax)
(out rep/integer status))
rep/integer)
;;; Block input
(DEFINE (%VM-READ-PARTIAL-BLOCK IOB LOC)
(receive (length status)
(ios_$get-partial (iob-channel iob)
(if (iob-interactive? iob)
0
ios_$no_rec_bndry_opt)
loc
(string-length loc)
nil)
; (format t "~&partial: sts= ~x len= ~d~%" status length)
(cond ((fx= 0 status)
(set (iob-eof-flag? iob) nil)
length)
((fx= aegis-eof status)
(set (iob-eof-flag? iob) t)
eof)
(else
(local-os-error status)))))
(define-foreign ios_$get-partial
("IOS_$GET" (in rep/integer-16-u port-id)
(in rep/integer-16-u put-get-options)
(ignore rep/string buffer)
(in rep/integer bufmax)
(out rep/integer status))
rep/integer)
;;; Output
(define (%VM-WRITE-BUFFER iob)
(cond ((fx> (iob-offset iob) 0)
(let ((status (ios_$put (iob-channel iob)
0
(iob-buffer iob)
(iob-offset iob)
nil)))
(cond ((fx= 0 status)
(set (iob-offset iob) 0))
(else
(local-os-error status))))))
(no-value))
(define-foreign ios_$put
("IOS_$PUT" (in rep/integer-16-u port-id)
(in rep/integer-16-u put-get-options)
(ignore rep/extend buffer)
(in rep/integer buffer-size)
(out rep/integer status))
ignore)
;;; Newline is system dependent because of OS's like VMS.
(define-integrable (%vm-newline iob)
(vm-write-char iob #\newline))
;;; Block output
(define (%VM-WRITE-BLOCK IOB LOC)
(check-status (ios_$put-string (iob-channel iob)
0
loc
(string-length loc)
'#f))
(no-value))
(define-foreign ios_$put-string
("IOS_$PUT" (in rep/integer-16-u port-id)
(in rep/integer-16-u put-get-options)
(ignore rep/string buffer)
(in rep/integer buffer-size)
(out rep/integer status))
ignore)
(define ios_$illegal_operation #x01270002)
(define (%VM-FORCE-OUTPUT IOB)
(let ((status (ios_$force_write_file (iob-channel iob) nil)))
(cond ((or (fx= status 0) (fx= status ios_$illegal_operation))
(no-value))
(else
(local-os-error status)))))
(define-foreign ios_$force_write_file
("IOS_$FORCE_WRITE_FILE" (in rep/integer-16-u port-id)
(out rep/integer status))
ignore)
;;; The rest of this file doesn't have to be implemented to get
;;; the Z System booted.
;;; Pathnames
;;; Pathnames are system dependent objects used for naming files
;;; internally. They should not be accessible outside of this file.
;;; FILESPEC - Something that ->FILENAME can handle
;;; FILENAME - The result of ->FILENAME
;;; PATHNAME - A string in the LOCAL-OS format
;;; (->PATHNAME filespec) => pathname
(define-constant name_$pnamelen_max 256)
(define-constant pathname? string?)
(define-constant pathname-length string-length)
;;; ->PATHNAME provides the VM with a portable interface to the
;;; various file systems.
(define (->pathname filespec)
(cond ((pathname? filespec) filespec)
((not (file-system-present?))
(vm-error "Filespecs must be strings in VM."))
((filename? filespec) (filename->string filespec))
(else
(filename->string (->filename filespec)))))
;;; Random Aegis definitions
(define-set-of ios_$open_options_t
ios_$no_open_delay_opt
ios_$write_opt
ios_$unregulated_opt
ios_$position_to_eof_opt
ios_$inquire_only_opt
)
(define-enumerated ios_$create_mode_t
ios_$no_pre_exist_mode
ios_$preserve_mode
ios_$recreate_mode
ios_$truncate_mode
ios_$make_backup_mode
ios_$loc_name_only_mode
)
;;; Aegis UID's
(define-constant (MAKE-UID_$T)
(make-bytev 8))
(define-constant UID_$NIL (make-uid_$t))
;;; File opening and closing.
;++ What about pads, sockets, etc.
;++ There should be a population of all open IOB's.
;++ What should the buffer size be?
(define default-buffer-size 1024)
(define (%vm-open-file caller fd modespec size)
(let* ((path (->pathname (if (iob? fd) (iob-id fd) fd)))
(len (pathname-length path))
(mode (mode->iob-mode caller fd modespec))
(size (if (iob-mode? mode iob/inquire) 0 size)))
(receive (port-id status)
(cond ((iob-mode? mode iob/read)
(ios_$open path len 0 nil))
((iob-mode? mode iob/write)
(ios_$create path
len
uid_$nil
ios_$truncate_mode
ios_$write_opt
nil
nil))
((iob-mode? mode iob/inquire)
(ios_$open path len ios_$inquire_only_opt nil))
((iob-mode? mode iob/append)
(ios_$create path
len
uid_$nil
ios_$preserve_mode
(fx-xor ios_$write_opt
ios_$position_to_eof_opt)
nil
nil))
(else
(unsupported-mode-error caller fd modespec)))
(cond ((fxN= 0 status) nil)
(else
(let ((iob (get-i/o-buffer %buffer-pool fd port-id mode size)))
;++ (set (table-entry open-port-table iob) (object-hash iob))
iob))))))
(define-foreign ios_$create
("IOS_$CREATE" (in rep/string name)
(in rep/integer-16-u namelength)
(in rep/extend type-uid)
(in rep/integer-16-u create-mode)
(in rep/integer-16-u open-options)
(out rep/integer-16-u port-id)
(out rep/integer status))
ignore)
(define-foreign ios_$open
("IOS_$OPEN" (in rep/string name)
(in rep/integer-16-u namelength)
(in rep/integer-16-u open-options)
(out rep/integer status))
rep/integer)
(define (%vm-close-file iob)
(check-status (ios_$close (iob-channel iob) nil)))
(define-foreign ios_$close
("IOS_$CLOSE" (in rep/integer-16-u port-id)
(out rep/integer status))
ignore)
;;; File mapping
(define-enumerated ms_$conc_mode_t
ms_$nr_xor_1w
ms_$cowriters)
(define-enumerated ms_$acc_mode_t
ms_$r
ms_$rx
ms_$wr
ms_$wrx
ms_$riw)
; do area's need UID's
(define (%VM-MAP-AREA FILESPEC SIZE)
(let* ((path (->pathname filespec))
(len (pathname-length path))
(size (fx* size 4)))
(if (not (file-exists? path))
(close-port (open-port path 'out)))
(receive (begin length status)
(ms_$mapl path len 0 size ms_$nr_xor_1w ms_$wr -1 nil nil)
(ignore length)
(check-status status)
(create-area filespec begin size nil))))
(define-foreign ms_$mapl
("MS_$MAPL" (in rep/string name)
(in rep/integer-16-u namelength)
(in rep/integer start)
(in rep/integer desired-length)
(in rep/integer-16-u concurency)
(in rep/integer-16-u access)
(in rep/integer-8-s extend)
(out rep/integer length)
(out rep/integer status))
rep/address)
(define (%VM-MAKE-AREA FILESPEC SIZE)
(let* ((path (->pathname filespec))
(len (pathname-length path))
(size (fx* size 4)))
(receive (begin status)
(ms_$crmapl path len 0 size ms_$nr_xor_1w nil)
(check-status status)
(create-area filespec begin size nil))))
(define-foreign ms_$crmapl
("MS_$CRMAPL" (in rep/string name)
(in rep/integer-16-u namelength)
(in rep/integer start)
(in rep/integer desired-length)
(in rep/integer-16-u concurency)
(out rep/integer status))
rep/address)
(define (%VM-UNMAP-AREA AREA)
(check-status (ms_$unmap (area-begin area) (area-size area) nil))
(no-value))
(define-foreign ms_$unmap
("MS_$UNMAP" (in rep/integer address)
(in rep/integer length)
(out rep/integer status))
ignore)
;(define-unimplemented (VM-REMAP-AREA AREA))
;;; Foreign Procedures - see foreign.doc.
;;; The syntax to define a foreign procedure is:
;;;
;;; (define-foreign name (aegis_name (IN rep0 name)
;;; (IN/OUT rep1 name)
;;; (OUT rep2 name)
;;; ...)
;;; return-rep)
;;;
;;; We return multiple values starting with the returned value and
;;; then the out paramaters in order, ignoring the return value
;;; if indicated.
(define-constant kg_$name_string 32)
(define (make-foreign-procedure symbol)
(let* ((s (symbol->string symbol))
(pad-length (fx- kg_$name_string
(fixnum-min (string-length s)
kg_$name_string)))
(xeno (make-foreign symbol))
(addr (kg_$lookup (string-append
s
(string-fill (make-string pad-length)
#\space)))))
(cond ((fxn= addr 0)
(set (mref-integer xeno 4) addr)
xeno)
(else
(error "KG-lookup on foreign procedure ~s failed" symbol)))))
;++ rep/address should be made to work correctly (cons a xenoid).
(define-foreign kg_$lookup
("KG_$LOOKUP" (in rep/string))
rep/address)
;;; Load an Aegis binary file.
;;; From /us/ins/loader.ins.pas .
(define-foreign pm_$load
("PM_$LOAD" (in rep/string) ;;; In Name: Univ Name_$Pname_T
(in rep/integer-16-u) ;;; In Len: Integer;
(in rep/integer-16-u) ;;; In Opts: PM_$Loader_Opts;
(in rep/integer-16-u) ;;; In N_Sects: Integer;
(ignore rep/extend) ;;; Out Info: Univ PM_$Load_Info;
(out rep/integer)) ;;; Out Status: Status_T
ignore)
(define-set-of pm_$opts
pm_$copy_proc
pm_$install
pm_$no_unresolveds
pm_$load_global
pm_$install_sections)
(define (load-foreign file)
(let ((out (standard-output) ))
(bind ((*load-level* (fx+ *load-level* 1)))
(comment-indent out (fx* *load-level* 2))
(format out "Loading foreign ~s~%" file)
(let* ((fname (->filename file))
(type (filename-type fname))
(file (->pathname (if (null? type)
(filename-with-type fname 'bin)
fname)))
(status (pm_$load file
(string-length file)
pm_$install
0
(make-bytev 8) ; 4+4+0*(32+4+4) = 8
0)))
(if (fxN= 0 status)
(error "Couldn't load ~S~%**~10t~a"
file
(local-os-error-message status)))))))